package com.qn.utils.excel;

import com.qn.annotations.PropertyName;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;

public class HSSF implements Excel {
    private HSSFSheet sheet;

    public HSSF() {

    }

    /**
     * 构造函数，初始化excel数据
     *
     * @param filePath  excel路径
     * @param sheetName sheet表名
     */
    @Override
    public void getSheet(String filePath, String sheetName) throws IOException {
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(filePath);
            HSSFWorkbook sheets = new HSSFWorkbook(fileInputStream);
            //获取sheet
            this.sheet = sheets.getSheet(sheetName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        fileInputStream.close();
    }

    @Override
    public List<String> getAllSheetNames(String filePath) throws IOException {
        FileInputStream fileInputStream = null;
        List<String> sheetNames = new ArrayList<>();
        try {
            fileInputStream = new FileInputStream(filePath);
            HSSFWorkbook sheets = new HSSFWorkbook(fileInputStream);
            for (int i = 0; i < sheets.getNumberOfSheets(); i++) {//获取每个Sheet表
                sheetNames.add(sheets.getSheetName(i));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        fileInputStream.close();
        return sheetNames;
    }

    /**
     * 根据行和列的索引获取单元格的数据
     *
     * @param row
     * @param column
     * @return
     */
    @Override
    public String getExcelDateByIndex(int row, int column) throws NullPointerException {
        HSSFRow row1 = sheet.getRow(row);
        String cell = row1.getCell(column).toString();
        return cell;
    }

    /**
     * 根据某一列值为“******”的这一行，来获取该行第x列的值
     *
     * @param caseName
     * @param currentColumn 当前单元格列的索引
     * @param targetColumn  目标单元格列的索引
     * @return
     */
    @Override
    public String getCellByCaseName(String caseName, int currentColumn, int targetColumn) {
        String operateSteps = "";
        //获取行数
        int rows = sheet.getPhysicalNumberOfRows();
        for (int i = 0; i < rows; i++) {
            HSSFRow row = sheet.getRow(i);
            String cell = row.getCell(currentColumn).toString();
            if (cell.equals(caseName)) {
                operateSteps = row.getCell(targetColumn).toString();
                break;
            }
        }
        return operateSteps;
    }

    /**
     * @param object 任意对象，该对象为Excel表格对应的对象
     * @return 返回一个被Excel表格数据填充的集合
     * @deprecated 获取表格当中的数据集
     */
    @Override
    public <T> List<T> depositExcelData(T object, int initRow) throws Exception {
        int lastField = 13;

        int rows = sheet.getPhysicalNumberOfRows();
        Class aClass = object.getClass();
        Field[] fields = aClass.getDeclaredFields();
        List<T> companyDataList = new LinkedList<>();
        // 属性指针
        int fieldIndex = 2;
        // 列错误时的指针
        int cellIndex = 0;
        // 是否出错
        boolean flag = true;
        // 属性是否到最后都没完成
        boolean isFlag = true;

        Field fieldLast = fields[lastField];
        fieldLast.setAccessible(true);


        // 这个算的比较复杂，可以选择垂直性的解析那个相对来说操作数更少，但是这个是第一个想到的就先实现了这个
        for (int i = 2; i < rows; i++) {
            HSSFRow row = sheet.getRow(i);
            T obj = (T) aClass.newInstance();
            for (int j = 0; j < 15; j++) {
                Field field = fields[fieldIndex];
                // 根据注解值和标题进行匹配
                field.setAccessible(true);
                PropertyName annotation = field.getAnnotation(PropertyName.class);
                String title = getExcelDateByIndex(1, j);
                // 成功时
                if (title.equals(annotation.name())) {
                    String cell = row.getCell(j).toString();
                    if ("-".equals(cell)) {
                        cell = null;
                    }
                    field.set(obj, cell);
                    fieldIndex++;
                    j = cellIndex;
                    flag = true;
                } else {
                    // 出错时标记索引
                    if (flag) {
                        cellIndex = j;
                        flag = false;
                    }

                    // 判断当前数据是否到表格最后一列都没有能匹配到属性
                    if (j >= 14 && field.get(obj) == null) {
                        if (isFlag) {
                            j = 0;
                            isFlag = false;
                        }
                    }
                }
            }

            isFlag = true;
            cellIndex = 0;
            fieldIndex = 2;
            companyDataList.add(obj);
        }
        return companyDataList;
    }

    /**
     * @deprecated 获取当前表格真是列数
     */
    public Integer getCurrentSheetCellsNum() {
        HSSFRow row = sheet.getRow(1);
        int cellsNum = row.getPhysicalNumberOfCells();
        int fieldIndex = 0;
        for (int i = 0; i < cellsNum; i++) {
            String value = row.getCell(i).toString();
            if ("".equals(value) || value == null) {
                fieldIndex = i;
                break;
            }
        }
        return fieldIndex;
    }
}
